(function($) {
    
    $.App   = function(options) {
        
        var socket          = io.connect('http://localhost:8080');
        var timeOutTyping   = null;
        
        Init();
        function Init() {
            authInit();
            
            roomInit();
            
            friendInit();
        }
        
        /**
         * Login and Logout
         */
        function authInit() {
            authEvent();
            
            authSocket();
        }
        
        /**
         * auth event function
         */
        function authEvent() {
            
            $('#usersList a.use').click(function(e) {
                var id = $(this).data('id');
                $('.popup-loading').show();
                socket.emit('auth-login', id);
            });
            
            $('#logoutBtn').click(function(e) {
                socket.emit('auth-logout');
            });
        }
        
        /**
         * auth Socket function
         */
        function authSocket() {
            
            socket.on('auth-logged', function(data) {
                $('#Popup').fadeOut('slow');                
                $('#authName').text(data.name);
                
                // Remove name after login.
                $('#friendsList .user'+data.id).remove();
            });
            
            socket.on('auth-joined', function(data) {                
                // Hide use button
                $('#usersList .user'+data).find('a.use').addClass('hide');
                
                // Show user is online
                $('#friendsList .user'+data).find('span.status').removeClass('hide');
            });
            
            socket.on('auth-visit', function(data) {
                $.each(data, function(i, id) {                    
                    // Hide use button
                    $('#usersList .user'+id).find('a.use').addClass('hide');
                    
                    // Show user is online
                    $('#friendsList .user'+id).find('span.status').removeClass('hide');                
                });
            });
            
            //Logout
            socket.on('auth-logout', function(data) {
                window.location.href = '';
            });
            
            socket.on('auth-leaved', function(data) {
                // Hide use button
                $('#usersList .user'+data).find('a.use').removeClass('hide');

                // Show user is online
                $('#friendsList .user'+data).find('span.status').addClass('hide');
            });
        }
        
        /**
         * Chat all
         */
        function roomInit() {
            
            roomEvent();
            
            roomSocket();
        }
        
        /**
         * Handle event
         */
        function roomEvent() {
            
            $('#roomSendBtn').click(function() {
                
                var message = $('#room_message_content').val();
                
                // Set message is empty
                $('#room_message_content').val('');
                
                socket.emit('mess-send', message);
                
            });
            
        }
        
        /**
         * Handle socket.io
         */
        function roomSocket() {
            
            socket.on('mess-send-new', function(data) {
                
                var li  = '';
                
                li  = $('#templateRoomMessage').html();
                
                li  = li.replace(/{AVATAR}/g, data.authInfo.avatar);
                li  = li.replace(/{NAME}/g, data.authInfo.name);
                li  = li.replace(/{CREATED}/g, data.mess.created);
                li  = li.replace(/{MESSAGE}/g, data.mess.message);
                
                
                $('.message-room-list').append(li);
                
                $('.scrollableAreaWrap').scrollTop( $('.scrollableAreaContent').height() );
            });
            
        }
        
        /**
         * Chat friend
         */
        function friendInit() {
            
            friendEvent();
            
            friendSocket();
        }
        
        /**
         * Handle event
         */
        function friendEvent() {            
            // Click on icon user
            $('#friendsList a').click(function(e) {
                
                var id      = $(this).data('id');
                var avatar  = $(this).find('img').attr('src');
                var name    = $(this).find('span.name').text();
                
                // Check new a window.
                if(!$('#chat'+id).length) {
                    friendWindowNew({id: id, avatar: avatar, name: name});
                }
                
                // Focus for input. Case 1
                friendWindowFocus('#chat'+id, true);
                
                
                
            });
            
            
            $('body').on('click', '#windowsChat li i.close', function() {
                $(this).closest('li').remove();
            });
            
            $('body').on({
                focus:function(e) {
                    friendWindowFocus($(this).closest('li'), false);
                },
                keydown:function(e) {
                    if(e.keyCode == 13 && ($.trim($(this).val()) != null) ) {
                        var data = {id: $(this).closest('li').data('id'),
                                    message: $.trim($(this).val())};
                        
                        // Show message.
                        friendMessageSend(data, true);
                        
                        // Send message to server.
                        socket.emit('friend-mess-send', data);
                    } else {                        
                        var id  = $(this).closest('li').data('id');
                        friendTyping(id);
                    }

                }
                
                
            }, '#windowsChat li input.input');
            
        }
        
        /**
         * Handle socket.io
         */
        function friendSocket() {
            
            // User receive message.
            socket.on('friend-mess', function(data) {
                if(!$('#chat'+data.id).length) {
                    var dataWindow  = $.extend(false, data, {avatar: 'images/avatars/'+data.avatar});
                    friendWindowNew(dataWindow);
                }
                
                // Show message
                friendMessageSend(data, false);
            });
            
            socket.on('friend-mess-typing', function(id) {
                if($('#chat'+id).length) {
                    $('#chat'+id).find('.typing').show();
                }
            });
            
            socket.on('friend-typing-stop', function(id) {
                if($('#chat'+id).length) {
                    $('#chat'+id).find('.typing').hide();
                }
            });
        }
        
        
        /**
         * Send message to friend
         */
        function friendMessageSend(data, me) {
            var li  = $('#chat'+data.id);
            
            if(me == true) {
                var div = $('#templateFriendMessageMe').html();
                li.find('input.input').val('');
            } else {
                var div = $('#templateFriendMessageGuest').html();
                div     = div.replace(/{ID}/g, data.messageId);
                div     = div.replace(/{AVATAR}/g, data.avatar);
                div     = div.replace(/{NAME}/g, data.name);
            }
            
            div = div.replace(/{MESSAGE}/g, data.message);
            
            li.find('.conversation').append(div).end()
                    .find('.layoutBody').scrollTop(li.find('.conversation').height());            
        }
        
        /**
         * append window chat.
         */
        function friendWindowNew(data) {
            var li = $('#templateFriendMessage').html();                   
            li  = li.replace(/{AVATAR}/g, data.avatar);
            li  = li.replace(/{NAME}/g, data.name);
            li  = li.replace(/{ID}/g, data.id);
            $('#windowsChat').append(li);
        }
        
        /**
         * focus.
         */
        function friendWindowFocus(selector, focusInput) {            
            $('#windowsChat').children('li').removeClass('focus');
            $(selector).addClass('focus');
            if(focusInput) $(selector).find('input.input').focus();
        }
        
        /**
         * User typing ...
         */
        function friendTyping(id) {
            socket.emit('friend-mess-typing', id);
            
            clearTimeout(timeOutTyping);
            timeOutTyping   = setTimeout(function() {
                socket.emit('friend-typing-stop', id);
            }, 2000);
            
        }
        
        
        
        
    }
    
})(jQuery);
    
$(document).ready(function(e) {
   $.App();
});